package org.example.cloudphoto.manager.websocket.picture.handler;

import cn.hutool.json.JSONUtil;
import groovyjarjarantlr4.v4.runtime.misc.NotNull;
import org.example.cloudphoto.enums.PictureEditMessageTypeEnum;
import org.example.cloudphoto.manager.websocket.picture.disruptor.PictureEditEventProducer;
import org.example.cloudphoto.manager.websocket.picture.model.PictureEditRequestMessage;
import org.example.cloudphoto.manager.websocket.picture.model.PictureEditResponseMessage;
import org.example.cloudphoto.manager.websocket.picture.strategy.PictureEditMessageStrategy;
import org.example.cloudphoto.manager.websocket.picture.strategy.PictureEditMessageStrategyFactory;
import org.example.cloudphoto.manager.websocket.picture.util.PictureEditBroadcaster;
import org.example.cloudphoto.model.User;
import org.example.cloudphoto.service.UserService;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import javax.annotation.Resource;
import java.util.Map;

@Component
public class PictureEditHandler extends TextWebSocketHandler {

    @Resource
    private PictureEditEventProducer pictureEditEventProducer;

    @Resource
    private UserService userService;

    @Resource
    private PictureEditBroadcaster broadcaster;

    @Resource
    private PictureEditMessageStrategyFactory strategyFactory;


    /**
     * 连接建立成功后触发
     *
     * @param session 会话
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // 保存会话到集合中
        User user = (User) session.getAttributes().get("user");
        Long pictureId = (Long) session.getAttributes().get("pictureId");
        broadcaster.addSession(pictureId, session);

        // 构造响应
        PictureEditResponseMessage pictureEditResponseMessage = new PictureEditResponseMessage();
        pictureEditResponseMessage.setType(PictureEditMessageTypeEnum.INFO.getValue());
        String message = String.format("%s加入编辑", user.getUserName());
        pictureEditResponseMessage.setMessage(message);
        pictureEditResponseMessage.setUser(userService.getUserVO(user));
        // 广播给同一张图片的用户
        broadcaster.broadcastToPicture(pictureId, pictureEditResponseMessage);
    }

    /**
     * 客户端消息的方法，根据消息类别执行不同的处理
     *
     * @param session 当前wbs会话
     * @param message 当前会话收到的信息
     * @throws Exception
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 将消息解析为 PictureEditMessage
        PictureEditRequestMessage pictureEditRequestMessage = JSONUtil.toBean(message.getPayload(), PictureEditRequestMessage.class);
        // 从 Session 属性中获取公共参数
        Map<String, Object> attributes = session.getAttributes();
        User user = (User) attributes.get("user");
        Long pictureId = (Long) attributes.get("pictureId");
        // 生产消息
        pictureEditEventProducer.publishEvent(pictureEditRequestMessage, session, user, pictureId);
    }

    /**
     * WebSocket 连接关闭时触发
     *
     * @param session 会话
     * @param status  关闭状态
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, @NotNull CloseStatus status) throws Exception {
        Map<String, Object> attributes = session.getAttributes();
        Long pictureId = (Long) attributes.get("pictureId");
        User user = (User) attributes.get("user");

        // 获取并执行退出编辑策略
        PictureEditMessageStrategy exitStrategy = strategyFactory.getStrategy(PictureEditMessageTypeEnum.EXIT_EDIT.getValue());
        exitStrategy.handle(null, session, user, pictureId);

        // 删除会话
        broadcaster.removeSession(pictureId, session);

        // 响应
        PictureEditResponseMessage pictureEditResponseMessage = new PictureEditResponseMessage();
        pictureEditResponseMessage.setType(PictureEditMessageTypeEnum.INFO.getValue());
        String message = String.format("%s离开编辑", user.getUserName());
        pictureEditResponseMessage.setMessage(message);
        pictureEditResponseMessage.setUser(userService.getUserVO(user));
        broadcaster.broadcastToPicture(pictureId, pictureEditResponseMessage);
    }





}
